/***********************************************************************************
 * 文件名： mcu_adc.h
 * 版本：1
 * 说明：
 * 		MDT10F272 的ADC外设驱动。使用说明见头文件。在 bsp-mdt10f272_config.h 文件中可配置初始状态
 * 修改记录：
 * 	2021/07/14: 初版
***********************************************************************************/
#ifndef _MCU_ADC_H
#define _MCU_ADC_H

#include "mcu.h"

#define ADC_DISCARD_NUM 2 // 转换通道之后需要抛弃的个数


// 为了伪函数优化曝光以下属性

extern bit _Adc_mADContinueRun;
extern u8 _Adc_mNowCH;
extern volatile bit _Adc_mRunning;
extern volatile u8 _Adc_RunTime;

#if ADC_DISCARD_NUM
extern u8 _Adc_mDiscard;
#endif



// ADC初始化，初始化后ADC将会使能
// 按照配置文件中的初始参数进行初始化。注意中断初始状态在 Mcu_Init 中已统一初始化
void Adc_Init();

// AD转换完成事件，一般在中断中调用，每次转换完毕都要调用
#define Adc_EvComplated(u8_adv)     \
{	\
	_Adc_RunTime = 0;\
	if (_Adc_mDiscard < ADC_DISCARD_NUM)	\
    {	\
		_Adc_mDiscard++;	\
        BUSY = 1;	/* 继续转换 */	\
    }	\
	else	\
	{	\
		_Adc_mRunning = false;	\
		Adc_EventDone(u8_adv);		/* 这里可能重新Start, start后Adc_mRunning为true */\
		if(_Adc_mADContinueRun)	\
		{	\
			Adc_Start(_Adc_mNowCH);	\
		}	\
	}\
}

#define Adc_EvTimer()		\
{	\
	if(_Adc_mRunning)_Adc_RunTime++;\
	if(_Adc_RunTime >= _ADC_RUN_TIMEOUT)\
	{\
		_Adc_mRunning = false;\
		_Adc_RunTime = 0;\
		Adc_EventError();\
	}\
}

// 设置AD转换参考电压，注意ADC正在转换时不要调用。
// u8_vref:参考电压，取值范见配置文件bsp-272cfg.h
void Adc_SetADCVref(u8 vref);

// 启动一次AD转换，并返回结果
// 将会等待ADC空闲，注意，如果在调用前启动了ADC单次异步转换任务，并在完成回调中始终启动转换，ADC将会一直繁忙，本函数会死等阻塞。
// 将会临时打断连续转换任务，转换时临时关闭了ADC中断
u8 Adc_GetValue(u8 vf, u8 ch);

// 【异步】启动一次AD转换
// u8_ch : 通道号，取值范见配置文件bsp-272cfg.h
// 转换完成后ADIF=1,如果开启ADC中断将会产生中断，可在中断服务函数中获取结果
void Adc_Start(u8 ch);

// 启动连续AD转换，在开启AD中断状态下，每次转换完成产生中断，可以在中断里读取结果
//ch: 通道号，取值范见配置文件bsp-272cfg.h
#define Adc_StartContinue(u8_ch)	\
{	\
	_Adc_mADContinueRun=true;\
	_Adc_mNowCH=u8_ch;\
	Adc_Start(u8_ch);\
}

// 关闭连续转换
#define Adc_StopContinue()	{_Adc_mADContinueRun = false; while (_Adc_mRunning); }


// 获取现在的通道
#define Adc_GetCH()     (ADS0 & 0xF0)

// 获取现在的参考电压
#define Adc_GetVref()   (ADS0 & 0x0F)

// 使能ADC
#define Adc_Enable()    ADC_EN = 1

// 失能ADC,注意下次开启要重新初始化
#define Adc_Disable()   ADC_EN = 0

// 获取最后一次转换结
#define Adc_GetResult() ADRESH

// 获取中断标志
#define Adc_GetIntFlag() ADIF

// 清除中断标志
#define Adc_ClrIntFlag() ADIF = 0

#endif